DataOutputAgent should limit events after ordering

This should fix #1044.

Akinori MUSHA 9 年之前
父节点
当前提交
fe50730033
共有 2 个文件被更改,包括 47 次插入1 次删除
  1. 41 1
      app/models/agents/data_output_agent.rb
  2. 6 0
      spec/models/agents/data_output_agent_spec.rb

+ 41 - 1
app/models/agents/data_output_agent.rb

@@ -175,6 +175,43 @@ module Agents
175 175
       interpolated['push_hubs'].presence || []
176 176
     end
177 177
 
178
+    def sorted_events(reload = false)
179
+      events =
180
+        if (event_ids = memory[:event_ids]) &&
181
+           memory[:events_order] == events_order &&
182
+           memory[:events_to_show] >= events_to_show
183
+          received_events.where(id: event_ids).to_a
184
+        else
185
+          memory[:last_event_id] = nil
186
+          reload = true
187
+          []
188
+        end
189
+
190
+      if reload
191
+        new_events =
192
+          if last_event_id = memory[:last_event_id]
193
+            received_events.order(id: :desc).where(Event.arel_table[:id].gt(last_event_id))
194
+          else
195
+            # dig at least twice as many events as the number of
196
+            # `events_to_show`
197
+            received_events.order(id: :desc).limit([source_ids.count, 2].max * events_to_show)
198
+          end.to_a
199
+        events = new_events.concat(events)
200
+        memory[:events_order] = events_order
201
+        memory[:events_to_show] = events_to_show
202
+        memory[:last_event_id] = events.first.try!(:id)
203
+      end
204
+
205
+      events = sort_events(events).last(events_to_show)
206
+
207
+      if reload
208
+        memory[:event_ids] = events.map(&:id)
209
+        save
210
+      end
211
+
212
+      events
213
+    end
214
+
178 215
     def receive_web_request(params, method, format)
179 216
       unless interpolated['secrets'].include?(params['secret'])
180 217
         if format =~ /json/
@@ -184,7 +221,7 @@ module Agents
184 221
         end
185 222
       end
186 223
 
187
-      source_events = sort_events(received_events.order(id: :desc).limit(events_to_show).to_a)
224
+      source_events = sorted_events()
188 225
 
189 226
       interpolation_context.stack do
190 227
         interpolation_context['events'] = source_events
@@ -251,6 +288,9 @@ module Agents
251 288
     def receive(incoming_events)
252 289
       url = feed_url(secret: interpolated['secrets'].first, format: :xml)
253 290
 
291
+      # Reload new events and update cache
292
+      sorted_events(true)
293
+
254 294
       push_hubs.each do |hub|
255 295
         push_to_hub(hub, url)
256 296
       end

+ 6 - 0
spec/models/agents/data_output_agent_spec.rb

@@ -248,6 +248,12 @@ describe Agents::DataOutputAgent do
248 248
         end
249 249
 
250 250
         it 'can reorder the events_to_show last events based on a Liquid expression' do
251
+          # Check that ordering takes place before limiting, not after
252
+          agent.options['events_to_show'] = 2
253
+          asc_content, _status, _content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json')
254
+          expect(asc_content['items'].map {|i| i["title"] }).to eq(["Evolving again", "Evolving yet again with a past date"])
255
+
256
+          agent.options['events_to_show'] = 40
251 257
           asc_content, _status, _content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json')
252 258
           expect(asc_content['items'].map {|i| i["title"] }).to eq(["Evolving", "Evolving again", "Evolving yet again with a past date"])
253 259